/**
 * 聊天室测试
 */

var log = require('../utils/log');
var proto_man = require('../netbus/proto_man');
const { json } = require('express');
require("./talk_room_proto.js"); //注册聊天协议的解码器

var STYPE_TALKROOM = 1;

var TalkCmd = {
	Enter: 1,		//用户进来
	Exit: 2,		//用户离开
	UserArrived: 3,	//别人进来
	UserExit: 4,	//别人离开

	SendMsg: 5,		//自己发送消息
	UseMsg: 6,		//别人发送消息
};

var Respones = {
	Ok: 1,
	Is_In_TalkRoom: -100, 	//玩家已经在聊天室
	Not_In_TalkRoom: -101, 	//玩家不在聊天室
	INVALD_OPT:-102, 		//玩家非法操作
	INVALD_PARAMS: -103, 	//玩家的的参数不对
}

/**
 * 广播其他用户
 * @param {*} ctype 命令号
 * @param {*} body  数据
 * @param {*} noto_user 等于null 是广播room里面的所有用户
 */
function broadcast_cmd(ctype, body, noto_user){
	var json_encode = null;
	var buf_encode = null;
	for (const key in room) {
		if (room[key] === noto_user) {
			continue;
		}

		//本来可以这样写，但是会编码多次
		// session.send_cmd(STYPE_TALKROOM,ctype,body);

		//这样只会编码一次
		if(session.proto_type == proto_man.PROTO_JSON){
			if(json_encode == null){
				json_encode = proto_man.encode_cmd(proto_man.PROTO_JSON,STYPE_TALKROOM,ctype,body);
			}
			session.send_encode_cmd(json_encode);
		}else if(session.proto_type == proto_man.PROTO_BUF){
			if(buf_encode == null){
				buf_encode = proto_man.encode_cmd(proto_man.PROTO_BUF,STYPE_TALKROOM,ctype,body);
			}
			session.send_encode_cmd(buf_encode);
		}
	}
}

//保存我们聊天室里面所有用户的
var room = {};

function on_user_enter_talkroom(session,body){
	if(!body.uname || !body.usex){
		session.send_cmd(STYPE_TALKROOM,TalkCmd.Enter,Respones.INVALD_PARAMS);
		return;
	}

	if(room[service.session_key]){ //已经在我们的聊天室
		session.send_cmd(STYPE_TALKROOM,TalkCmd.Enter,Respones.Is_In_TalkRoom);
		return;
	}

	//告诉我们的客户端，你已经进入成功
	session.send_cmd(STYPE_TALKROOM,TalkCmd.Enter,Respones.Ok);
	//end 

	//把我们进来的消息广播给其他人
	broadcast_cmd(TalkCmd.UserArrived,body,session);
	// end

	//把在聊天室的人发送给我们刚进来的用户
	for (const key in room) {
		session.send_cmd(STYPE_TALKROOM,TalkCmd.UserArrived,room[key].uinfo);
	}
	//end

	//保存玩家信息到聊天室
	var talkman = {
		session:session,
		uinfo:body,
	};
	room[session.session_key] = talkman;
	// end
}

/**
 * 
 * @param {*} session 
 * @param {*} is_lost_connect  是否是自己主动离开,不是被迫断线, false 是主动离开 true是断线离开
 */
function on_user_exit_talkroon(session,is_lost_connect){
	//不在我们的聊天室
	if(!room[service.session_key]){
		if(!is_lost_connect){//
			session.send_cmd(STYPE_TALKROOM,TalkCmd.Exit,Respones.Not_In_TalkRoom);
		}
		return;
	}

	//把我们进来的消息广播给其他人
	broadcast_cmd(TalkCmd.Exit,room[service.session_key].uinfo,session);
	// end

	//把自己的数据从聊天室删除
	room[service.session_key] = null;
	delete room[service.session_key];
	//end

	//发送命令，你已经成功离开
	if(!is_lost_connect){
		session.send_cmd(STYPE_TALKROOM,Exit.Enter,Respones.Ok);
	}
	//end
}

//用户发送消息
function on_user_send_msg(session,msg){
	//验证是否在我们的聊天室
	if(!room[service.session_key]){
		session.send_cmd(STYPE_TALKROOM,TalkCmd.SendMsg,{
			0:Respones.INVALD_OPT,
		});
		return;
	}

	//发送成功
	session.send_cmd(STYPE_TALKROOM,TalkCmd.SendMsg,{
		0:Respones.Ok,
		1:room[service.session_key].uinfo.uname,
		2:room[service.session_key].uinfo.usex,
		3:msg,
	});
	// end

	//告诉其他人这个人发送了一个消息
	broadcast_cmd(STYPE_TALKROOM,TalkCmd.UseMsg,{
		0:room[service.session_key].uinfo.uname,
		1:room[service.session_key].uinfo.usex,
		2:msg,
	})
	// end
}

var service = {
    stype: STYPE_TALKROOM, // 服务号
	name: "talk room ", // 服务名称

	// 每个服务初始化的时候调用
	init: function () {
		log.info(this.name + 'service init');	
	},

	// 每个服务收到数据的时候调用
	on_recv_player_cmd: function(session, ctype, body) {
        log.info(this.name + 'service inon_recv_player_cmdit',ctype,body);	

		switch (ctype) {
			case TalkCmd.Enter:
				on_user_enter_talkroom(session,body)
				break;

			case TalkCmd.Exit: //主动请求离开
				//false 自己主动离开
				on_user_exit_talkroon(session,false);
				break;

			case TalkCmd.SendMsg: //用户发送消息
				on_user_send_msg(session,body);
				break;	
			default:
				break;
		}
	},

	// 每个服务连接丢失后调用,被动丢失连接
	on_player_disconnect: function(session) {
        log.info(this.name + 'service on_player_disconnect',session.session_key);
		//被迫掉线	
		on_user_exit_talkroon(session,true);
	}, 
};  

module.exports = service;